<template>
  <el-dialog
    v-model="dialogFormVisible"
    title="Shipping address"
    width="500"
    @close="resetForm"
  >
    <el-form
      ref="formEl"
      :model="form"
      :rules="rules"
      :label-width="formLabelWidth"
    >
      <el-row v-if="!newUser && manualUnlockPolicy && props.user?.Locked">
        <el-alert
          v-if="v$.value.form.manualUnlock.$dirty"
          :title="$t('pageUserManagement.modal.clickSaveToUnlockAccount')"
          type="warning"
          center
          show-icon
        />
        <el-alert
          v-else
          :title="$t('pageUserManagement.modal.accountLocked')"
          type="warning"
          center
          show-icon
        />
      </el-row>
      <el-form-item :label="$t('pageUserManagement.modal.accountStatus')">
        <el-radio-group v-model="form.status" class="ml-4">
          <el-radio :value="true" size="large">
            {{ $t('global.status.enabled') }}
          </el-radio>
          <el-radio :value="false" size="large">
            {{ $t('global.status.disabled') }}
          </el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item
        :label="$t('pageUserManagement.modal.username')"
        prop="username"
      >
        <el-col>
          <el-alert
            :title="
              $t($t('pageUserManagement.modal.cannotStartWithANumber')) +
              ',' +
              $t('pageUserManagement.modal.noSpecialCharactersExceptUnderscore')
            "
            type="warning"
            :closable="false"
          />
        </el-col>
        <el-col>
          <el-input
            style="width: 240px"
            v-model="form.username"
            :disabled="!newUser && originalUsername === 'root'"
          />
        </el-col>
      </el-form-item>
      <el-form-item
        :label="$t('pageUserManagement.modal.privilege')"
        prop="privilege"
      >
        <el-col>
          <el-select
            v-model="form.privilege"
            :placeholder="$t('pageUserManagement.modal.privilege')"
            style="width: 240px"
          >
            <el-option
              v-for="(item, key) in privilegeTypes"
              :key="key"
              :label="item"
              :value="item"
            />
          </el-select>
        </el-col>
      </el-form-item>
      <el-form-item
        v-if="newUser"
        prop="newPassword"
        :label="$t('pageSessions.modal.newPassword')"
      >
        <el-input
          style="width: 240px"
          v-model="form.password"
          autocomplete="off"
          type="password"
          show-password
        />
      </el-form-item>
      <el-form-item
        v-if="newUser"
        prop="passwordConfirmation"
        :label="$t('pageSessions.modal.confirmPassword')"
      >
        <el-input
          style="width: 240px"
          v-model="form.passwordConfirmation"
          autocomplete="off"
          type="password"
          show-password
        />
      </el-form-item>
      <el-form-item
        prop="maxDaysExpired"
        :label="$t('pageUserManagement.modal.maxDaysExpired')"
      >
        <el-input
          style="width: 240px"
          v-model="form.maxDaysExpired"
          autocomplete="off"
        />
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="closeModal()">
          {{ $t('global.action.cancel') }}
        </el-button>
        <el-button type="primary" @click="handleSubmit">
          {{ $t('global.action.save') }}
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import useVuelidateTool from '@/hooks/useVuelidateTool';
import { useUserManagementStore } from '@/store/UserSecurity/UserManagement/UserManagementStore';

const userManagementStore = useUserManagementStore();
const formLabelWidth = '120px';

const {
  useVuelidate,
  required,
  numeric,
  minLength,
  maxLength,
  requiredIf,
  pattern,
  sameAs,
  elementInputValidator,
} = useVuelidateTool();

const formEl = ref();
const emit = defineEmits(['ok', 'hidden']);
const dialogFormVisible = ref(false);
defineExpose({ dialogFormVisible });
const props = defineProps<{
  user: { Locked: boolean } | undefined;
  passwordRequirements: { minLength: number; maxLength: number };
}>();

const originalUsername = ref('');
const form = reactive({
  originalUsername: '',
  status: true,
  username: '',
  privilege: null,
  password: '',
  passwordConfirmation: '',
  manualUnlock: false,
  maxDaysExpired: '',
});

const password = toRef(form, 'password');

const newUser = computed(() => {
  return props.user ? false : true;
});
const accountSettings = computed(() => {
  return userManagementStore.accountSettings;
});
const manualUnlockPolicy = computed(() => {
  return accountSettings.value.lockoutDuration;
});
const privilegeTypes = computed(() => {
  return userManagementStore.accountRoles;
});

watch(
  () => props.user,
  (
    value: {
      [index: string]: any;
    } | null,
  ) => {
    if (value === null) return;
    originalUsername.value = value.username;
    form.username = value.username;
    form.status = value.Enabled;
    form.privilege = value.privilege;
    form.maxDaysExpired = value.PasswordExpirationDays;
  },
);

watch(dialogFormVisible, () => {
  nextTick(() => formEl.value.clearValidate());
});

const v$ = useVuelidate(
  {
    status: {
      required,
    },
    username: {
      required,
      maxLength: maxLength(16),
      pattern: pattern.value(/^([a-zA-Z_][a-zA-Z0-9_]*)/),
    },
    privilege: {
      required,
    },
    password: {
      required: requiredIf(function () {
        return requirePassword();
      }),
      minLength: minLength(props.passwordRequirements.minLength),
      maxLength: maxLength(props.passwordRequirements.maxLength),
    },
    passwordConfirmation: {
      required: requiredIf(function () {
        return requirePassword();
      }),
      confirmPassword: sameAs(password),
    },
    manualUnlock: {},
    maxDaysExpired: {
      numeric,
    },
  },
  form,
);

const rules = computed(() => {
  return {
    status: [
      {
        trigger: 'change',
        validator: elementInputValidator.value(v$, 'status'),
      },
    ],
    username: [
      {
        trigger: 'change',
        validator: elementInputValidator.value(v$, 'username'),
      },
    ],
    privilege: [
      {
        trigger: 'change',
        validator: elementInputValidator.value(v$, 'privilege'),
      },
    ],
    password: [
      {
        trigger: 'change',
        validator: elementInputValidator.value(v$, 'password'),
      },
    ],
    passwordConfirmation: [
      {
        trigger: 'change',
        validator: elementInputValidator.value(v$, 'passwordConfirmation'),
      },
    ],
    manualUnlock: [
      {
        trigger: 'change',
        validator: elementInputValidator.value(v$, 'manualUnlock'),
      },
    ],
    maxDaysExpired: [
      {
        trigger: 'change',
        validator: elementInputValidator.value(v$, 'maxDaysExpired'),
      },
    ],
  };
});

const handleSubmit = () => {
  let userData: {
    [index: string]: string | boolean | null;
  } = {};
  v$.value.$touch();
  if (newUser.value) {
    if (v$.value.$invalid) return;
    userData.username = form.username;
    userData.status = form.status;
    userData.privilege = form.privilege;
    userData.password = form.password;
    userData.maxdaysexpired = form.maxDaysExpired;
  } else {
    if (v$.value.$invalid) {
      if (
        v$.value.form.password.required ||
        v$.value.form.passwordConfirmation.required
      )
        return;
      else {
        if (
          v$.value.form.manualUnlock.$error ||
          v$.value.form.maxDaysExpired.$error ||
          v$.value.form.privilege.$error ||
          v$.value.form.status.$error ||
          v$.value.form.username.$error
        )
          return;
      }
    }
    userData.originalUsername = originalUsername.value;
    if (v$.value.status.$dirty) {
      userData.status = form.status;
    }
    if (v$.value.username.$dirty) {
      userData.username = form.username;
    }
    if (v$.value.privilege.$dirty) {
      userData.privilege = form.privilege;
    }
    if (v$.value.password.$dirty && v$.value.password.required) {
      userData.password = form.password;
    }
    if (v$.value.maxDaysExpired.$dirty) {
      userData.maxdaysexpired = form.maxDaysExpired;
    }
    if (v$.value.manualUnlock.$dirty) {
      // If form manualUnlock control $dirty then
      // set user Locked property to false
      userData.locked = false;
    }
    if (Object.entries(userData).length === 1) {
      closeModal();
      return;
    }
  }
  emit('ok', { isNewUser: newUser.value, userData });
  closeModal();
};
const closeModal = () => {
  nextTick(() => {
    dialogFormVisible.value = false;
  });
};
const resetForm = () => {
  form.originalUsername = '';
  form.status = true;
  form.username = '';
  form.privilege = null;
  form.password = '';
  form.passwordConfirmation = '';
  form.maxDaysExpired = '';
  emit('hidden');
  formEl.value.clearValidate();
};
const requirePassword = () => {
  if (newUser.value) return true;
  return false;
};
</script>

<style lang="scss">
.el-form-item__label {
  justify-content: flex-start;
}
</style>
